import os
import pytest
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.firefox.service import Service as FirefoxService
from selenium.webdriver.edge.service import Service as EdgeService
from config.config import driver_cfg  # 导入配置管理器
from config.constants import *  # 导入路径常量


def configure_browser_options(options):
    """优化后的浏览器选项配置方法

    参数:
        options: 浏览器选项对象(ChromeOptions/FirefoxOptions/EdgeOptions)

    功能:
        1. 配置无头模式参数
        2. 设置性能相关参数
        3. 添加安全相关参数
        4. 配置浏览器特有参数
    """

    # 安全相关配置(添加多个安全相关的浏览器参数)
    security_args = [
        "--no-sandbox",  # 禁用沙箱(通常在容器环境中需要)
        "--disable-dev-shm-usage",  # 避免使用/dev/shm(解决Docker内存问题)
        "--disable-notifications",  # 禁用通知弹窗
        "--disable-infobars"  # 禁用"Chrome正受自动化控制"提示栏
    ]
    # 批量添加安全参数(使用分号连接多个参数)
    options.add_argument(";".join(security_args)) if hasattr(options, 'add_argument') else None

    # Chrome/Edge特有配置(检查是否有 add_experimental_option 方法)
    if hasattr(options, 'add_experimental_option'):
        # 启动时最大化窗口
        options.add_argument("--start-maximized")
        # 排除自动化检测开关
        options.add_experimental_option("excludeSwitches", ["enable-automation"])
        # 禁用自动化扩展
        options.add_experimental_option("useAutomationExtension", False)
        # 允许所有远程来源(跨域)
        options.add_argument("--remote-allow-origins=*")


@pytest.fixture(scope="function")
def driver():
    """
    特点:
    - 使用constants.py中定义的驱动路径
    - 增强的错误处理和日志
    - 更安全的属性访问方式
    返回:
        WebDriver实例
    异常:
        当浏览器初始化失败时，会抛出异常并标记测试为失败
    """
    # 从配置管理器获取浏览器类型，默认为'chrome'，并转换为小写
    browser_type = driver_cfg['browser'].lower()
    driver = None  # 初始化driver变量

    # 驱动路径映射(定义浏览器类型到对应类/路径的映射)
    DRIVER_MAP = {
        "chrome": (webdriver.ChromeOptions, ChromeService, CHROME_DRIVER_PATH),
        "firefox": (webdriver.FirefoxOptions, FirefoxService, FIREFOX_DRIVER_PATH),
        "edge": (webdriver.EdgeOptions, EdgeService, EDGE_DRIVER_PATH)
    }

    # 检查浏览器类型是否支持
    if browser_type not in DRIVER_MAP:
        pytest.skip(f"不支持的浏览器类型: {browser_type}")

    # 解包映射值：选项类、服务类和驱动路径
    options_class, service_class, driver_path = DRIVER_MAP[browser_type]

    try:
        # 验证驱动文件是否存在
        if not os.path.exists(driver_path):
            raise FileNotFoundError(f"驱动文件不存在: {driver_path}")

        # 初始化浏览器选项
        options = options_class()
        # 配置浏览器选项
        configure_browser_options(options)

        # 创建浏览器服务实例
        service = service_class(executable_path=driver_path)
        # 动态获取浏览器驱动类
        driver_class = getattr(webdriver, browser_type.capitalize())
        # 实例化浏览器驱动
        driver = driver_class(service=service, options=options)

        # 返回driver实例供测试使用
        yield driver

    except Exception as e:
        # 捕获异常并标记测试为失败
        pytest.fail(f"浏览器初始化失败 - {type(e).__name__}: {str(e)}")
        raise

    finally:
        # 无论测试成功与否，最后都会退出driver
        driver and driver.quit()  # 如果driver存在则调用quit()